import { createClient } from 'redis'
import type { RedisClientType } from 'redis'
import { ConfigService } from '@nestjs/config'
import { Injectable, Logger } from '@nestjs/common'
import { ConfigEnum } from '@/common/enums/config.enum'

@Injectable()
export class RedisService {
  private readonly redisClient: RedisClientType
  private logger = new Logger(RedisService.name)

  constructor(private readonly configService: ConfigService) {
    // 从配置服务获取Redis连接配置
    const redisConfig = this.configService.get(ConfigEnum.REDIS)
    // 创建 Redis 客户端
    this.redisClient = createClient(redisConfig)
    this.redisClient.on('connect', () => this.logger.log('Redis 客户端已连接'))
    this.redisClient.on('ready', () => this.logger.log('Redis 服务器已就绪'))
    this.redisClient.on('reconnecting', () => this.logger.log('Redis 正在重连...'))
    this.redisClient.on('end', () => this.logger.log('Redis 连接已断开'))
    this.redisClient.on('error', (error) => this.logger.error(`Redis 连接错误 ${error.message}`))
    this.redisClient.connect()
  }

  public async set(key: string, value: string) {
    await this.redisClient.set(key, value)
  }

  public async setEx(key: string, value: string, expired: number = 0) {
    await this.redisClient.setEx(key, expired, value)
  }

  public async get(key: string) {
    return this.redisClient.get(key)
  }

  public async getEx(key: string, ttl: number): Promise<string | null> {
    const value = await this.redisClient.get(key)
    if (!value) return null
    if (ttl > 0) await this.redisClient.expire(key, ttl)
    return value
  }

  public async del(keys: string | string[]) {
    await this.redisClient.del(keys)
  }

  public keys(pattern: string): Promise<string[]> {
    return this.redisClient.keys(pattern)
  }

  public async expire(key: string, ttl: number): Promise<boolean> {
    const expireResult = await this.redisClient.expire(key, ttl)
    return expireResult === 1
  }

  /**
   * 获取 Redis 客户端实例
   * 提供类型安全的客户端访问
   */
  public getClient(): RedisClientType {
    return this.redisClient
  }
}
